home *** CD-ROM | disk | FTP | other *** search
/ MPEG Toolkit / MPEG Toolkit.iso / dos / mpegstat / parseblo.c < prev    next >
C/C++ Source or Header  |  1997-01-01  |  12KB  |  466 lines

  1. /* MPEGSTAT - analyzing tool for MPEG-I video streams
  2.  * 
  3.  * Technical University of Berlin, Germany, Dept. of Computer Science
  4.  * Tom Pfeifer - Multimedia systems project - pfeifer@fokus.gmd.de
  5.  *
  6.  * Jens Brettin, Harald Masche, Alexander Schulze, Dirk Schubert
  7.  *
  8.  * This program uses parts of the source code of the Berkeley MPEG player
  9.  *
  10.  * ---------------------------
  11.  *
  12.  * Copyright (c) 1993 Technical University of Berlin, Germany
  13.  *
  14.  * for the parts of the Berkeley player used:
  15.  *
  16.  * Copyright (c) 1992 The Regents of the University of California.
  17.  * All rights reserved.
  18.  *
  19.  * ---------------------------
  20.  *
  21.  * Permission to use, copy, modify, and distribute this software and its
  22.  * documentation for any purpose, without fee, and without written agreement is
  23.  * hereby granted, provided that the above copyright notices and the following
  24.  * two paragraphs appear in all copies of this software.
  25.  * 
  26.  * IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA 
  27.  * or the Technical University of Berlin BE LIABLE TO ANY PARTY FOR
  28.  * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
  29.  * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY OF
  30.  * CALIFORNIA or the Technical University of Berlin HAS BEEN ADVISED OF THE 
  31.  * POSSIBILITY OF SUCH DAMAGE.
  32.  * 
  33.  * THE UNIVERSITY OF CALIFORNIA and the Technical University of Berlin 
  34.  * SPECIFICALLY DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
  35.  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
  36.  * PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND THE 
  37.  * UNIVERSITY OF CALIFORNIA and the Technical University of Berlin HAVE NO 
  38.  * OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, 
  39.  * OR MODIFICATIONS.
  40.  */
  41. #define NO_SANITY_CHECKS
  42. #include <assert.h>
  43. #include "video.h"
  44. #include "proto.h"
  45. #include "decoders.h"
  46. #include "dither.h"
  47.  
  48. /* External declarations. */
  49.  
  50. extern int zigzag_direct[];
  51.  
  52. /* Macro for returning 1 if num is positive, -1 if negative, 0 if 0. */
  53.  
  54. #define Sign(num) ((num > 0) ? 1 : ((num == 0) ? 0 : -1))
  55.  
  56.  
  57. /*
  58.  *--------------------------------------------------------------
  59.  *
  60.  * ParseReconBlock --
  61.  *
  62.  *    Parse values for block structure from bitstream.
  63.  *      n is an indication of the position of the block within
  64.  *      the macroblock (i.e. 0-5) and indicates the type of 
  65.  *      block (i.e. luminance or chrominance). Reconstructs
  66.  *      coefficients from values parsed and puts in 
  67.  *      block.dct_recon array in vid stream structure.
  68.  *      sparseFlag is set when the block contains only one
  69.  *      coeffictient and is used by the IDCT.
  70.  *
  71.  * Results:
  72.  *    
  73.  *
  74.  * Side effects:
  75.  *      Bit stream irreversibly parsed.
  76.  *
  77.  *--------------------------------------------------------------
  78.  */
  79.  
  80. #define DCT_recon blockPtr->dct_recon
  81. #define DCT_dc_y_past blockPtr->dct_dc_y_past
  82. #define DCT_dc_cr_past blockPtr->dct_dc_cr_past
  83. #define DCT_dc_cb_past blockPtr->dct_dc_cb_past
  84.  
  85. #define DECODE_DCT_COEFF_FIRST DecodeDCTCoeffFirst
  86. #define DECODE_DCT_COEFF_NEXT DecodeDCTCoeffNext
  87.  
  88. void
  89. ParseReconBlock(n)
  90.      int n;
  91. {
  92. #ifdef RISC
  93.   unsigned int temp_curBits;
  94.   int temp_bitOffset;
  95.   int temp_bufLength;
  96.   unsigned int *temp_bitBuffer;
  97. #endif
  98.  
  99.   Block *blockPtr = &curVidStream->block;
  100.   int coeffCount;
  101.   
  102.   if (bufLength < 100)
  103.     correct_underflow();
  104.  
  105. #ifdef RISC
  106.   temp_curBits = curBits;
  107.   temp_bitOffset = bitOffset;
  108.   temp_bufLength = bufLength;
  109.   temp_bitBuffer = bitBuffer;
  110. #endif
  111.  
  112.   {
  113.     /*
  114.      * Copy the globals curBits, bitOffset, bufLength, and bitBuffer
  115.      * into local variables with the same names, so the macros use the
  116.      * local variables instead.  This allows register allocation and
  117.      * can provide 1-2 fps speedup.  On machines with not so many registers,
  118.      * don't do this.
  119.      */
  120. #ifdef RISC
  121.     register unsigned int curBits = temp_curBits;
  122.     register int bitOffset = temp_bitOffset;
  123.     register int bufLength = temp_bufLength;
  124.     register unsigned int *bitBuffer = temp_bitBuffer;
  125. #endif
  126.  
  127.     int diff;
  128.     int size, level, i, run, pos, coeff;
  129.     short int *reconptr;
  130.     unsigned char *iqmatrixptr, *niqmatrixptr;
  131.     int qscale;
  132.  
  133.     reconptr = DCT_recon[0];
  134.  
  135.     /* 
  136.      * Hand coded version of memset that's a little faster...
  137.      * Old call:
  138.      *    memset((char *) DCT_recon, 0, 64*sizeof(short int));
  139.      */
  140.     {
  141.       INT32 *p;
  142.       p = (INT32 *) reconptr;
  143.  
  144.       p[0] = p[1] = p[2] = p[3] = p[4] = p[5] = p[6] = p[7] = p[8] = p[9] = 
  145.       p[10] = p[11] = p[12] = p[13] = p[14] = p[15] = p[16] = p[17] = p[18] =
  146.       p[19] = p[20] = p[21] = p[22] = p[23] = p[24] = p[25] = p[26] = p[27] =
  147.       p[28] = p[29] = p[30] = p[31] = 0;
  148.  
  149.     }
  150.  
  151.     if (curVidStream->mblock.mb_intra) {
  152.  
  153.       if (n < 4) {
  154.  
  155.     /*
  156.      * Get the luminance bits.  This code has been hand optimized to
  157.      * get by the normal bit parsing routines.  We get some speedup
  158.      * by grabbing the next 16 bits and parsing things locally.
  159.      * Thus, calls are translated as:
  160.      *
  161.      *    show_bitsX  <-->   next16bits >> (16-X)
  162.      *    get_bitsX   <-->   val = next16bits >> (16-flushed-X);
  163.      *               flushed += X;
  164.      *               next16bits &= bitMask[flushed];
  165.      *    flush_bitsX <-->   flushed += X;
  166.      *               next16bits &= bitMask[flushed];
  167.      *
  168.      * I've streamlined the code a lot, so that we don't have to mask
  169.      * out the low order bits and a few of the extra adds are removed.
  170.      *    bsmith
  171.      */
  172.     unsigned int next16bits, index, flushed;
  173.  
  174.     show_bits16(next16bits);
  175.     index = next16bits >> (16-7);
  176.     size = dct_dc_size_luminance[index].value;
  177.     flushed = dct_dc_size_luminance[index].num_bits;
  178.     next16bits &= bitMask[16+flushed];
  179.  
  180.     if (size != 0) {
  181.       flushed += size;
  182.       diff = next16bits >> (16-flushed);
  183.           if (!(diff & bitTest[32-size])) {
  184.         diff = rBitMask[size] | (diff + 1);
  185.       }
  186.     } else {
  187.       diff = 0;
  188.     }
  189.     flush_bits(flushed);
  190.  
  191.     if (n == 0) {
  192.       coeff = diff << 3;
  193.       if (curVidStream->mblock.mb_address -
  194.           curVidStream->mblock.past_intra_addr > 1) 
  195.         coeff += 1024;
  196.       else coeff += DCT_dc_y_past;
  197.       DCT_dc_y_past = coeff;
  198.     } else {
  199.       coeff = DCT_dc_y_past + (diff << 3);
  200.       DCT_dc_y_past = coeff;
  201.     }
  202.       } else {
  203.     
  204.     /*
  205.      * Get the chrominance bits.  This code has been hand optimized to
  206.      * as described above
  207.      */
  208.     unsigned int next16bits, index, flushed;
  209.  
  210.     show_bits16(next16bits);
  211.     index = next16bits >> (16-8);
  212.     size = dct_dc_size_chrominance[index].value;
  213.     flushed = dct_dc_size_chrominance[index].num_bits;
  214.     next16bits &= bitMask[16+flushed];
  215.     
  216.     if (size != 0) {
  217.       flushed += size;
  218.       diff = next16bits >> (16-flushed);
  219.           if (!(diff & bitTest[32-size])) {
  220.         diff = rBitMask[size] | (diff + 1);
  221.       }
  222.     } else {
  223.       diff = 0;
  224.     }
  225.     flush_bits(flushed);
  226.     
  227.     if (n == 4) {
  228.       coeff = diff << 3;
  229.       if (curVidStream->mblock.mb_address -
  230.           curVidStream->mblock.past_intra_addr > 1) 
  231.         coeff += 1024;
  232.       else coeff += DCT_dc_cr_past;
  233.       DCT_dc_cr_past = coeff;
  234.  
  235.     } else {
  236.       coeff = diff << 3;
  237.       if (curVidStream->mblock.mb_address -
  238.           curVidStream->mblock.past_intra_addr > 1) 
  239.         coeff += 1024;
  240.       else coeff += DCT_dc_cb_past;
  241.       DCT_dc_cb_past = coeff;
  242.     }
  243.       }
  244.       
  245.       *reconptr = coeff;
  246.       i = 0; pos = 0;
  247.       coeffCount = (coeff != 0);
  248.     
  249.       if (curVidStream->picture.code_type != 4) {
  250.     
  251.     qscale = curVidStream->slice.quant_scale;
  252.     mvstat (qscale, 4);
  253.     iqmatrixptr = curVidStream->intra_quant_matrix[0];
  254.     
  255.     while(1) {
  256.       
  257.       DECODE_DCT_COEFF_NEXT(run, level);
  258.  
  259.       if (run == END_OF_BLOCK) break;
  260.  
  261.       i = i + run + 1;
  262.       pos = zigzag_direct[i];
  263.       coeff = (level * qscale * ((int) iqmatrixptr[pos])) >> 3;
  264.       if (level < 0) {
  265.           coeff += (coeff & 1);
  266.       } else {
  267.           coeff -= (coeff & 1);
  268.       }
  269.  
  270.       reconptr[pos] = coeff;
  271.       if (coeff) {
  272.         coeffCount++;
  273.       }
  274.  
  275.     }
  276.  
  277.  
  278.     {
  279.       extern unsigned int *mbCoeffPtr;
  280.       mbCoeffPtr[pos]++;
  281.     }
  282.  
  283.     flush_bits(2);
  284.  
  285.     goto end;
  286.       }
  287.     }
  288.     
  289.     else {
  290.       
  291.       niqmatrixptr = curVidStream->non_intra_quant_matrix[0];
  292.       qscale = curVidStream->slice.quant_scale;
  293.       
  294.       DECODE_DCT_COEFF_FIRST(run, level);
  295.       i = run;
  296.  
  297.       pos = zigzag_direct[i];
  298.       if (level < 0) {
  299.       coeff = (((level<<1) - 1) * qscale * 
  300.            ((int) (niqmatrixptr[pos]))) >> 4; 
  301.       coeff += (coeff & 1);
  302.       } else {
  303.       coeff = (((level<<1) + 1) * qscale * 
  304.            ((int) (*(niqmatrixptr+pos)))) >> 4; 
  305.       coeff -= (coeff & 1);
  306.       }
  307.       reconptr[pos] = coeff;
  308.       if (coeff) {
  309.     coeffCount = 1;
  310.       }
  311.  
  312.       if (curVidStream->picture.code_type != 4) {
  313.     
  314.     while(1) {
  315.       
  316.       DECODE_DCT_COEFF_NEXT(run, level);
  317.  
  318.       if (run == END_OF_BLOCK) break;
  319.  
  320.       i = i+run+1;
  321.       pos = zigzag_direct[i];
  322.       if (level < 0) {
  323.           coeff = (((level<<1) - 1) * qscale * 
  324.                ((int) (niqmatrixptr[pos]))) >> 4; 
  325.           coeff += (coeff & 1);
  326.       } else {
  327.           coeff = (((level<<1) + 1) * qscale * 
  328.                ((int) (*(niqmatrixptr+pos)))) >> 4; 
  329.           coeff -= (coeff & 1);
  330.       }
  331.       reconptr[pos] = coeff;
  332.       if (coeff) {
  333.         coeffCount++;
  334.       }
  335.     }
  336.  
  337.     {
  338.       extern unsigned int *mbCoeffPtr;
  339.       mbCoeffPtr[pos]++;
  340.     }
  341.  
  342.     flush_bits(2);
  343.  
  344.     goto end;
  345.       }
  346.     }
  347.     
  348.   end:
  349.  
  350.     if (coeffCount == 1) j_rev_dct_sparse (reconptr, pos);
  351.     else j_rev_dct(reconptr);
  352.  
  353. #ifdef RISC
  354.     temp_curBits = curBits;
  355.     temp_bitOffset = bitOffset;
  356.     temp_bufLength = bufLength;
  357.     temp_bitBuffer = bitBuffer;
  358. #endif
  359.  
  360.   }
  361.  
  362. #ifdef RISC
  363.   curBits = temp_curBits;
  364.   bitOffset = temp_bitOffset;
  365.   bufLength = temp_bufLength;
  366.   bitBuffer = temp_bitBuffer;
  367. #endif
  368. }
  369.     
  370. #undef DCT_recon 
  371. #undef DCT_dc_y_past 
  372. #undef DCT_dc_cr_past 
  373. #undef DCT_dc_cb_past 
  374.  
  375.  
  376. /*
  377.  *--------------------------------------------------------------
  378.  *
  379.  * ParseAwayBlock --
  380.  *
  381.  *    Parses off block values, throwing them away.
  382.  *      Used with grayscale dithering.
  383.  *
  384.  * Results:
  385.  *    None.
  386.  *
  387.  * Side effects:
  388.  *      None.
  389.  *
  390.  *--------------------------------------------------------------
  391.  */
  392.  
  393. void
  394. ParseAwayBlock(n)
  395.      int n;
  396. {
  397.   unsigned int diff;
  398.   unsigned int size, run;
  399.   int level;
  400.  
  401.   if (bufLength < 100)
  402.     correct_underflow();
  403.  
  404.   if (curVidStream->mblock.mb_intra) {
  405.  
  406.     /* If the block is a luminance block... */
  407.  
  408.     if (n < 4) {
  409.  
  410.       /* Parse and decode size of first coefficient. */
  411.  
  412.       DecodeDCTDCSizeLum(size);
  413.  
  414.       /* Parse first coefficient. */
  415.  
  416.       if (size != 0) {
  417.     get_bitsn(size, diff);
  418.       }
  419.     }
  420.  
  421.     /* Otherwise, block is chrominance block... */
  422.  
  423.     else {
  424.  
  425.       /* Parse and decode size of first coefficient. */
  426.  
  427.       DecodeDCTDCSizeChrom(size);
  428.  
  429.       /* Parse first coefficient. */
  430.  
  431.       if (size != 0) {
  432.     get_bitsn(size, diff);
  433.       }
  434.     }
  435.   }
  436.  
  437.   /* Otherwise, block is not intracoded... */
  438.  
  439.   else {
  440.  
  441.     /* Decode and set first coefficient. */
  442.  
  443.     DECODE_DCT_COEFF_FIRST(run, level);
  444.   }
  445.  
  446.   /* If picture is not D type (i.e. I, P, or B)... */
  447.  
  448.   if (curVidStream->picture.code_type != 4) {
  449.  
  450.     /* While end of macroblock has not been reached... */
  451.  
  452.     while (1) {
  453.  
  454.       /* Get the dct_coeff_next */
  455.  
  456.       DECODE_DCT_COEFF_NEXT(run, level);
  457.  
  458.       if (run == END_OF_BLOCK) break;
  459.     }
  460.  
  461.     /* End_of_block */
  462.  
  463.     flush_bits(2);
  464.   }
  465. }
  466.